package com.csii.activiti.server.abstraction.lock.impl;

import com.csii.activiti.server.abstraction.lock.ActLockService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class ActLockServiceImpl implements ActLockService {
    @Value("${activity.lock.length:50}")
    private int lockArrLength;

    private Lock[] locks;

    @PostConstruct
    private void init(){
        locks = new ReentrantLock[lockArrLength];
        for (int i = 0; i < locks.length; i++) {
            locks[i] = new ReentrantLock();
        }
    }

    @Override
    public void lock(String key) {
        locks[getIndex(key)].lock();
    }

    @Override
    public void unlock(String key) {
        locks[getIndex(key)].unlock();
    }


    private int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    private int getIndex(Object key){
        return (locks.length-1) & hash(key);
    }
}
